/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_artifact_action.cpp

	$Header: /heroes4/script_artifact_action.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "script_artifact_action.h"

#include "adv_artifact_pile.h"
#include "streambuf_operators.h"
#include "default_artifacts.h"
#include "sized_int_types.h"
#include "enum_operations.h"
#include "artifact_slot.h"
#include "basic_dialog.h"

namespace {
	static std::list<t_artifact>	g_artifacts_transferred;
};

// --------------------------------------------------------------------------
// t_script_artifact_action class
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

bool t_script_artifact_action::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	if ( !t_script_stack_action::read_from_map( stream, format_version ) )
		return false;

	int artifact_count = get< t_uint16 >( stream );
	m_artifacts.resize( artifact_count );

	t_artifact_list::iterator artifact_end = m_artifacts.end();
	t_artifact_list::iterator artifact_iter = m_artifacts.begin();
	for ( ; artifact_iter != artifact_end; ++artifact_iter )
	{
		if ( !::read_from_map( stream, *artifact_iter ) )
			return false;
	}
	return true;
}

bool t_script_artifact_action::read( std::streambuf& stream, int version )
{
	if (t_script_stack_action::read( stream, version ) == false) 
		return false;

	int count =  get < t_uint16 >( stream );
	m_artifacts.resize( count );

	t_artifact_list::iterator artifact_end = m_artifacts.end();
	t_artifact_list::iterator artifact_iter = m_artifacts.begin();
	for ( ; artifact_iter != artifact_end; ++artifact_iter )
	{
		if (artifact_iter->read( stream ) == false)
			return false;
	}

	return true;
}

bool  t_script_artifact_action::write( std::streambuf& stream ) const
{
	if (!t_script_stack_action::write( stream ))
		return false;

	put < t_uint16 >( stream, m_artifacts.size() );

	t_artifact_list::const_iterator artifact_end = m_artifacts.end();
	t_artifact_list::const_iterator artifact_iter = m_artifacts.begin();
	for ( ; artifact_iter != artifact_end; ++artifact_iter )
	{
		if (artifact_iter->write( stream ) == false)
			return false;
	}

	return true;
}

void t_script_artifact_action::add_icons(t_basic_dialog* dialog) const
{
	while (!g_artifacts_transferred.empty()) {
		dialog->add_artifact( g_artifacts_transferred.back() );
		g_artifacts_transferred.pop_back();
	}
}

void t_script_give_artifact::make_adjustment(t_creature_stack* stack, t_creature_array* owning_array) const
{
	g_artifacts_transferred.clear();

	t_artifact_list const &	artifacts = get_artifacts();
	int size = artifacts.size();
	for(int i = 0; i < size; i++) 
	{
		stack->add(artifacts[i]);
		g_artifacts_transferred.push_back(artifacts[i]);
	}

	if ( owning_array && owning_array->is_graveyard() )
	{
		t_adv_artifact_pile::pull_artifacts_from_array( *owning_array, NULL );
	}
}

void t_script_give_artifact::make_adjustment(t_creature_array* array) const
{
	g_artifacts_transferred.clear();

	t_artifact_list const &	artifacts = get_artifacts();
	int size = artifacts.size();
	for(int i = 0; i < size; i++)
	{
		array->add(artifacts[i]);
		g_artifacts_transferred.push_back(artifacts[i]);
	}

	if ( array && array->is_graveyard() )
	{
		t_adv_artifact_pile::pull_artifacts_from_array( *array, NULL );
	}
}

void t_script_take_artifact::make_adjustment(t_creature_stack* stack, t_creature_array* owning_array) const
{
	g_artifacts_transferred.clear();

	t_artifact_list const &	artifacts = get_artifacts();
	int artifact_cnt = artifacts.size();
	for (int i = 0; i < artifact_cnt; i++) {
		t_artifact_type type = artifacts[i].get_icon();

		int slot_cnt = stack->get_backpack_count();
		for (int j = 0; j < slot_cnt; j++) {
			if (stack->get_backpack_slot(j).get_icon() == type) {
				stack->remove_backpack(j);
				g_artifacts_transferred.push_back(artifacts[i]);
				continue;
			}
		}

		t_hero* hero = stack->get_hero();
		if (hero) {
			for (t_artifact_slot slot = k_artifact_slot_bow; slot < k_artifact_slot_hero_count; enum_incr(slot)) {
				if (hero->get_artifact(slot).get_icon() == type) {
					hero->remove(slot);
					g_artifacts_transferred.push_back(artifacts[i]);
					continue;
				}
			}
		}
	}
}

void t_script_take_artifact::make_adjustment(t_creature_array* array) const
{
	// Search thru all the backpacks, and then check the slots.
	t_artifact_list const &	artifacts = get_artifacts();
	int artifact_cnt = artifacts.size();
	for (int i = 0; i < artifact_cnt; i++) {
		t_artifact_type type = artifacts[i].get_icon();
		bool found_artifact = false;

		for (int j = 0; (j < t_creature_array::k_size) && (!found_artifact); j++) {
			t_creature_stack *stack = &(*array)[j];
			if (stack == NULL) continue;

			int slot_cnt = stack->get_backpack_count();
			for (int k = 0; k < slot_cnt; k++) {
				if (stack->get_backpack_slot(k).get_icon() == type) {
					stack->remove_backpack(k);
					found_artifact = true;
					break;
				}
			}
		}

		for (int j = 0; (j < t_creature_array::k_size) && (!found_artifact); j++) {
			t_creature_stack *stack = &(*array)[j];
			if (stack == NULL) continue;

			t_hero* hero = stack->get_hero();
			if (hero) {
				for (t_artifact_slot slot = k_artifact_slot_bow; slot < k_artifact_slot_hero_count; enum_incr(slot)) {
					if (hero->get_artifact(slot).get_icon() == type) {
						hero->remove(slot);
						found_artifact = true;
					}
				}
			}
		}
	}
	
}

